package dslab.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * class that stores all data necessary for the task of adding a message, which will
 * be executed in a concurrency safe manner at the next opportunity
 *
 * stores message to be added, as well as all recipients this message is intended for
 */
public class AddMessageTask implements WriteTask {
    private final String componentId;
    private final Message message;
    private final List<String> users;
    private final Map<String, List<Message>> mails;

    /**
     * constructs an AddMessageTask object
     * @param componentId name of component
     * @param message message to be stored, will take a shallow reference and make a deep copy itself
     * @param users list of users to store message for, will take a shallow reference and make a deep copy itself
     * @param mails reference to store of all mails
     */
    public AddMessageTask(String componentId, Message message, List<String> users, Map<String, List<Message>> mails) {
        // clone message and users for concurrency reasons
        this.message = new Message(message);
        this.users = new ArrayList<>(users);
        // inherit id and mail store reference
        this.componentId = componentId;
        this.mails = mails;
    }

    @Override
    public void executeTask() {
        // get and announce users
        System.out.printf("@%s: executing add message task with message%s for users %s%n", componentId, message, Arrays.toString(users.toArray()));
        // for all users that are recipients of the message
        // (users are already verified to exist, by the DMAPProtocol)
        for (String user : users) {
            List<Message> userMails = mails.get(user);
            // add that message
            userMails.add(new Message(message));
        }
    }
}
